/*
============================================================================
Name        : pd_load_lib.cpp
Author      : Jian(raphyer@hotmail.com)
Version     :
Copyright   : GPL
Description : Symbian Load dynamic Library implement 
============================================================================
*/

// INCLUDE FILES
#include "pd_load_lib.h"
#include <e32base.h>        // symbian base
#include <e32std.h>			// RLibrary
#include <string.h>			// strlen()
#include <stdlib.h>			// atoi()


#define LOADLIB_PANIC(e) ( User::Panic( _L("Load Library Error"), e ) )

static RLibrary* _load_lib(const char* path) ;


void pd_lib_unload(void* lib) 
{
    RLibrary* sLib = (RLibrary*)lib ;
    sLib->Close() ;
    delete sLib ;
}


void* pd_lib_load(const char* path) 
{
    void* lib = NULL ;
    TRAPD(error, lib = (void*)_load_lib(path)) ;
    if (error != KErrNone)
    {
        /* TODO: log some error msg */
        return NULL ;
    }
    return lib ;
}

lua_CFunction pd_lib_find_fun (void *lib, const char *sym) 
{
    TInt len = strlen( sym ) ;

    __ASSERT_DEBUG(*(sym + len - 2) == '@', LOADLIB_PANIC(1)) ;

    TInt fIndex = atoi(sym + len - 1);

    __ASSERT_DEBUG(fIndex > 0 , LOADLIB_PANIC(1)) ;

    TLibraryFunction fn ;
    fn = ((RLibrary*)lib)->Lookup( fIndex ) ;
    return (lua_CFunction)fn ;
}

static RLibrary* _load_lib(const char *path)
{
    TPtrC8 ptr( (const TUint8*)path ) ;
    HBufC* libName = HBufC::NewLC( ptr.Length() ) ;
    libName->Des().Copy( ptr ) ;

    __ASSERT_DEBUG( libName->Length() < 256 , 0 ) ;

    RLibrary* lib = new(ELeave)RLibrary ;
    CleanupClosePushL( *lib ) ;
    User::LeaveIfError( lib->Load( *libName ) );
    CleanupStack::Pop( lib ) ;
    CleanupStack::PopAndDestroy( libName ) ;

    return lib ;
}

/* End of File */
